struct file
, defined in <include/linux/fs.h>, is the second most important data structurestruct file, defined in <include/linux/fs.h>, is the second most important data structure
used in device drivers. Note that a file has nothing to do with the FILE pointers of
user-space programs
struct file 代表了一個已開啟的文件,它是一個內核空間的結構,與用戶空間的 FILE 完全無關。該結構主要用於管理文件的開啟和操作
filp->f_dentry->d_inode
訪問 inode 結構。Example (include/linux/fs.h): Linux-6.6
/*
* f_{lock,count,pos_lock} members can be highly contended and share
* the same cacheline. f_{lock,mode} are very frequently used together
* and so share the same cacheline as well. The read-mostly
* f_{path,inode,op} are kept on a separate cacheline.
*/
struct file {
union {
struct llist_node f_llist;
struct rcu_head f_rcuhead;
unsigned int f_iocb_flags;
};
/*
* Protects f_ep, f_flags.
* Must not be taken from IRQ context.
*/
spinlock_t f_lock;
fmode_t f_mode;
atomic_long_t f_count;
struct mutex f_pos_lock;
loff_t f_pos;
unsigned int f_flags;
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
struct path f_path;
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* needed for tty driver, and maybe others */
void *private_data;
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct hlist_head *f_ep;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
errseq_t f_wb_err;
errseq_t f_sb_err; /* for syncfs */
} __randomize_layout
__attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
補充: file_handle
file_handle 是 Linux 中的結構體,常用於系統調用(例如 name_to_handle_at() 和 open_by_handle_at())
struct file_handle {
__u32 handle_bytes;
// 這通常用來標識句柄所屬的文件系統類型。不同的文件系統可能會定義不同類型的句柄以便能正確識別文件
int handle_type;
/* file identifier */
// flexible array member,其大小由 handle_bytes 指定。它實際上存放了文件的識別符。不同文件系統可能會將不同的資訊存儲在這裡,具體取決於文件系統的實現
unsigned char f_handle[] __counted_by(handle_bytes);
};
fd 與 fhandle 的主要區別在於使用場景:
The inode structure is used by the kernel internally to represent files. Therefore, it is
different from the file structure that represents an open file descriptor
struct inode 是用來代表文件的數據結構,與文件描述符(file descriptor)無關。每個文件在內核中對應一個 inode,而每個 struct file 都會指向相應的 inode
簡化版範例 (include/linux/fs.h): Linux-6.6
struct inode {
umode_t i_mode; /* 文件類型和權限 */
kuid_t i_uid; /* 文件擁有者的用戶 ID */
kgid_t i_gid; /* 文件擁有者的組 ID */
unsigned long i_ino; /* inode 編號 */
dev_t i_rdev; /* 設備編號(特別對於設備文件) */
loff_t i_size; /* 文件大小(以字節為單位) */
struct timespec64 i_atime; /* 最後一次訪問時間 */
struct timespec64 i_mtime; /* 最後一次修改時間 */
struct timespec64 i_ctime; /* inode 最後修改時間(狀態變更時間) */
unsigned int i_nlink; /* 硬連接數 */
blkcnt_t i_blocks; /* 文件所佔用的區塊數 */
struct super_block *i_sb; /* 指向文件系統的 super block */
const struct inode_operations *i_op; /* inode 操作方法 */
const struct file_operations *i_fop; /* 文件操作方法 */
struct address_space *i_mapping; /* 文件內容的映射 */
atomic_t i_count; /* inode 引用計數 */
};
路徑: include/linux/fdtable.h
struct fdtable {
unsigned int max_fds;
struct file __rcu **fd; /* current fd array */
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
struct rcu_head rcu;
};
/*
* Open file table structure
*/
struct files_struct {
/*
* read mostly part
*/
atomic_t count;
bool resize_in_progress;
wait_queue_head_t resize_wait;
struct fdtable __rcu *fdt;
struct fdtable fdtab;
/*
* written part on a separate cache line in SMP
*/
spinlock_t file_lock ____cacheline_aligned_in_smp;
unsigned int next_fd;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
unsigned long full_fds_bits_init[1];
struct file __rcu * fd_array[NR_OPEN_DEFAULT];
};
每個 Process 都有一個 struct files_struct,其中包含該進程開啟的所有文件的資訊
進程 (process)
|
|---> struct files_struct
|
|---> struct fdtable
|
|---> fd[0] --> struct file (代表標準輸入)
|
|---> fd[1] --> struct file (代表標準輸出)
|
|---> fd[2] --> struct file (代表標準錯誤)